using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;


namespace  EasyNetWork
{
    /// <summary>
    /// 链表范围。
    /// </summary>
    /// <typeparam name="T">指定链表范围的元素类型。</typeparam>
    public class LinkedListRange<T> : IEnumerable<T>,IEnumerable
    {
        private readonly LinkedListNode<T> m_First; //链表起点
        private readonly LinkedListNode<T> m_Terminal; //链表终点

        /// <summary>
        /// 初始化链表范围类的新实例
        /// </summary>
        /// <param name="first"></param>
        /// <param name="terminal"></param>
        /// <exception cref="Exception"></exception>
        public LinkedListRange(LinkedListNode<T> first,LinkedListNode<T> terminal)
        {
            if (first == null || terminal == null || first == terminal)
            {
                throw new  System.Exception("使用错误");
            }

            m_First = first;
            m_Terminal = terminal;
        }
        
        /// <summary>
        /// 获取链表范围是否有效
        /// </summary>
        public bool IsValid
        {
            get
            {
                return m_First != null && m_Terminal != null && m_First != m_Terminal;
            }
        }
        
        /// <summary>
        /// 获取链表范围的开始节点
        /// </summary>
        public LinkedListNode<T> First
        {
            get
            {
                return m_First;
            }
        }

        /// <summary>
        /// 获取链表范围的终结标记结点
        /// </summary>
        public LinkedListNode<T> Terminal
        {
            get
            {
                return m_Terminal;
            }
        }
        
        /// <summary>
        /// 获取链表范围的长度
        /// </summary>
        public int Count
        {
            get
            {
                if (!IsValid)
                {
                    return 0;
                }

                int count = 0;
                //从开始节点遍历到结束节点，获取链表范围长度
                for (LinkedListNode<T> current = m_First; current != null && current != m_Terminal; current = current.Next)
                {
                    count++;
                }

                return count;
            }
        }

        public bool Contains(T value)
        {
            //从开始节点遍历到结束节点，获取链表范围内是否存在指点节点
            for (LinkedListNode<T> current = m_First; current != null && current != m_Terminal; current = current.Next)
            {
                if (current.Value.Equals(value))
                {
                    return true;
                }
            }

            return false;
        }
        
        /// <summary>
        /// 返回循环访问集合的枚举数。
        /// </summary>
        /// <returns>循环访问集合的枚举数。</returns>
        public Enumerator GetEnumerator()
        {
            return new Enumerator(this);
        }

        /// <summary>
        /// 返回循环访问集合的枚举数。
        /// </summary>
        /// <returns>循环访问集合的枚举数。</returns>
        IEnumerator<T> IEnumerable<T>.GetEnumerator()
        {
            return GetEnumerator();
        }
        
        /// <summary>
        /// 返回循环访问集合的枚举数。
        /// </summary>
        /// <returns>循环访问集合的枚举数。</returns>
        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
        
        public struct Enumerator : IEnumerator<T>,IEnumerator
        {
            private readonly LinkedListRange<T> m_LinkedListRange;
            private LinkedListNode<T> m_current;
            private T m_currentValue;

            internal Enumerator(LinkedListRange<T> range)
            {
                if (!range.IsValid)
                {
                    throw new System.Exception("Range is invalid");
                }

                m_LinkedListRange = range;
                m_current = m_LinkedListRange.First;
                m_currentValue = default(T);
            }
            /// <summary>
            /// 获取当前节点
            /// </summary>
            public T Current
            {
                get
                {
                    return m_currentValue;
                }
            }
            
            /// <summary>
            /// 获取当前的枚举数
            /// </summary>
            object IEnumerator.Current
            {
                get
                {
                    return m_currentValue;
                }
            }
            
            /// <summary>
            /// 清理枚举数
            /// </summary>
            public void Dispose()
            {
                
            }
            
            /// <summary>
            /// 获取下一个节点
            /// </summary>
            /// <returns></returns>
            public bool MoveNext()
            {
                if (m_current == null || m_current == m_LinkedListRange.m_Terminal)
                {
                    return false;
                }

                m_currentValue = m_current.Value;
                m_current = m_current.Next;
                return true;
            }

            void IEnumerator.Reset()
            {
                m_current = m_LinkedListRange.First;
                m_currentValue = default(T);
            }
        }
    }
}
